package edu.upenn.cis.cis550.hw3.client;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import edu.upenn.cis.cis550.hw3.shared.Relation;
import edu.upenn.cis.cis550.hw3.shared.Tuple;

/**
 * This is the main class for generating Web table results for CIS 550 HW1
 * 
 * @author zives
 * 
 */
public class CopyOftestHomepage implements EntryPoint {

    int userid = 14;

    Grid topPhotos = new Grid(2, 5);

    VerticalPanel recomPanel = new VerticalPanel();

    VerticalPanel photoPanel = new VerticalPanel();

    MultiWordSuggestOracle oracle;

    FlexTable recomTable = new FlexTable();

    private final QueryTablesAsync queryService = GWT.create(QueryTables.class);

    private final QueryRecomAsync recomService = GWT.create(QueryRecom.class);

    private final UpdateTablesAsync updateService = GWT.create(UpdateTables.class);

    /**
     * This is the entry point method.
     */

    public void onModuleLoad() {

        recomPanel.addStyleName("westWidget");

        // Assemble Main panel.

        DockLayoutPanel appPanel = new DockLayoutPanel(Unit.PCT);

        appPanel.addWest(recomPanel, 20);
        appPanel.add(photoPanel);

        RootLayoutPanel.get().add(appPanel);

        buildRecomPanel();
        // refreshRecommendations();
        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                System.out.println("fail.");

            }

            public void onSuccess(Relation result) {
                refreshRecommendations();

            }
        };

        queryService.getFriends(userid, callback);

        testPhotos();

    }

    private void testPhotos() {
        populateOracle();
        photoPanel.add(buildPhotoFrame(111,
                "http://xml.coverpages.org/images/ibm.gif", 3.2));
        photoPanel.add(buildPhotoFrame(112,
                "http://www.kirupa.com/net/images/xml_doc2.gif", 1.2));
    }

    private void populateOracle() {
        oracle = new MultiWordSuggestOracle();

        AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {

            public void onFailure(Throwable caught) {
                System.out.println("fail.");

            }

            public void onSuccess(ArrayList<String> result) {
                for (String s : result) {
                    oracle.add(s);
                }

            }
        };

        queryService.getAllTags(callback);

    }

    private void buildRecomPanel() {
        recomPanel.add(recomTable);
    }

    private void refreshRecommendations() {

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                // System.out.println(caught.toString());
                System.out.println("Failure");
                caught.printStackTrace();
            }

            public void onSuccess(Relation result) {
                if (!result.isEmpty()) {
                    Iterator<Tuple> i = result.iterator();
                    while (i.hasNext()) {
                        int rows = recomTable.getRowCount();
                        final Tuple t = i.next();
                        final String fid = t.getValue("recomID").toString();

                        String name = t.getValue("recomID") + t.getValue("firstName").toString() + " " + t.getValue("lastName").toString();
                        // System.out.println(name);
                        // String name = t.getValue(0).toString();
                        // System.out.println(t.getSchema().toString());

                        //String name = t.getValue("recomID").toString();
                        Button b = new Button("Add friend");
                        b.addClickHandler(new ClickHandler() {

                            public void onClick(ClickEvent event) {
                                Button b = (Button) event.getSource();
                                addFriend(fid);
                                b.setText("Added!");
                                b.setEnabled(false);

                            }
                        });

                        recomTable.setText(rows, 0, name);
                        recomTable.setWidget(rows, 1, b);

                    }
                } else {
                    System.out.println("empty set");
                }

            }
        };
        
        System.out.println("calling allFriendsRecom");

        recomService.getAllFriendRecom(Integer.toString(userid), callback);

    }

    public void addFriend(String fid) {
        System.out.println("Adding friend");

        AsyncCallback<String> callback = new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                System.out.println("Adding friend failure");

            }

            public void onSuccess(String result) { // TODO Auto-generated method
                System.out.println("Success");

            }
        };
        
        System.out.println("callback made");
        System.out.println(userid + " " + Integer.parseInt(fid) + " ");
        updateService.addFriend(userid, Integer.parseInt(fid), "default", callback);

    }

    private VerticalPanel buildPhotoFrame(final int pid, String url, double avgScore) {
        VerticalPanel photoFrame = new VerticalPanel();

        Image photo = new Image(url);
        photo.setTitle(Double.toString(avgScore));
        HorizontalPanel tagsPanel = new HorizontalPanel();
        final SuggestBox tagBox = new SuggestBox(oracle);
        tagBox.addKeyPressHandler(new KeyPressHandler() {

            public void onKeyPress(KeyPressEvent event) {
               if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
                   addTag(tagBox.getText(), pid);
               }
                
            }
            
        });
        tagsPanel.add(tagBox);

        HorizontalPanel ratingPanel = new HorizontalPanel();
        final ListBox lb = new ListBox();
        lb.addItem("1");
        lb.addItem("2");
        lb.addItem("3");
        lb.addItem("4");
        lb.addItem("5");
        lb.setVisibleItemCount(1);
        lb.addChangeHandler(new ChangeHandler() {

            public void onChange(ChangeEvent event) {
                changeRating(userid,pid, lb.getValue(lb.getSelectedIndex()));

            }
        });
        ratingPanel.add(lb);

        photoFrame.add(photo);
        photoFrame.add(tagsPanel);
        photoFrame.add(ratingPanel);

        return photoFrame;
    }

    protected void changeRating(int uid, int pid, String rating) {
      System.out.println("Changing rating to " + rating + "for user " + uid + "on pic " + pid);
        /*updateService.addRating(uid, pid, Integer.parseInt(rating), new AsyncCallback<String>() {

        public void onFailure(Throwable caught) {
            // TODO Auto-generated method stub
            
        }

        public void onSuccess(String result) {
            // TODO Auto-generated method stub
            
        }
           
       });
       */
        
    }

    protected void addTag(String text, int pid) {
        oracle.add(text);
        updateService.addTag(pid, text, new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                caught.printStackTrace();
                
            }

            public void onSuccess(String result) {
                System.out.println(result);
                
            }
            
        });
        
    }
}
